package com.molichuxing.services.infrastructure.service.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.services.infrastructure.bean.EnterpriseScheduleBean;
import com.molichuxing.services.infrastructure.convertor.Convert;
import com.molichuxing.services.infrastructure.dao.EnterpriseScheduleMapper;
import com.molichuxing.services.infrastructure.dto.request.create.EnterpriseScheduleCreateDto;
import com.molichuxing.services.infrastructure.dto.response.EnterpriseScheduleDto;
import com.molichuxing.services.infrastructure.service.EnterpriseScheduleService;
import com.molichuxing.services.property.EnterpriseScheduleStateEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 企业排期
 *
 * @author zhaopenghui
 * @date 2020年6月3日
 */
@Service("enterpriseScheduleService")
public class EnterpriseScheduleServiceImpl implements EnterpriseScheduleService {

    @Resource
    private EnterpriseScheduleMapper enterpriseScheduleMapper;


    @Override
    public Paged<EnterpriseScheduleDto> getSchedulePage(Map<String, Object> params, int pageNum, int pageSize) throws Exception {
        long pageCount = enterpriseScheduleMapper.getPageCount(params);
        if (pageCount <= 0) {
            return new Paged<>(null, 0, pageSize);
        }

        List<EnterpriseScheduleBean> storeBeanList = enterpriseScheduleMapper.getPage(params, pageNum, pageSize);
        List<EnterpriseScheduleDto> storeDtoList = Convert.toEnterpriseScheduleDtoList(storeBeanList);
        return new Paged<>(storeDtoList, pageCount, pageSize);
    }

    @Override
    public Integer getScheduleCount() {
        return enterpriseScheduleMapper.getScheduleCount();
    }

    @Override
    public Integer getScheduleOverdueCount() {
        return enterpriseScheduleMapper.getScheduleOverdueCount();
    }

    /**
     * 获取排期信息
     *
     * @param scheduleIds
     * @return
     */
    @Override
    public List<EnterpriseScheduleDto> getScheduleByScheduleIds(List<Integer> scheduleIds) {
        List<EnterpriseScheduleBean> scheduleByScheduleIds = enterpriseScheduleMapper.getScheduleByScheduleIds(scheduleIds);
        return Convert.toEnterpriseScheduleDtoList(scheduleByScheduleIds);
    }

    /**
     * 详情
     *
     * @param scheduleId
     * @return
     */
    @Override
    public EnterpriseScheduleDto getScheduleById(Integer scheduleId) {
        if (null == scheduleId) {
            return null;
        }
        return Convert.toEnterpriseScheduleDto(enterpriseScheduleMapper.getById(scheduleId));
    }

    /**
     * 新增订单排期信息
     *
     * @param createDto 新增信息
     * @return Integer id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Integer create(EnterpriseScheduleCreateDto createDto) {
        EnterpriseScheduleBean bean = Convert.toEnterpriseScheduleBean(createDto);
        enterpriseScheduleMapper.create(bean);
        return bean.getId();
    }

    /**
     * 终止订单排期
     *
     * @param orderCode 订单号
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean modifyTermination(Long orderCode) {
        EnterpriseScheduleBean scheduleBean = enterpriseScheduleMapper.getCurrent(orderCode, EnterpriseScheduleStateEnum.NO.getValue());
        if (scheduleBean == null) {
            return true;
        }

        return enterpriseScheduleMapper.modifyTermination(orderCode, EnterpriseScheduleStateEnum.NO.getValue(),
                EnterpriseScheduleStateEnum.TERMINATION.getValue()) > 0;
    }

    /**
     * 获取企业订单排期信息
     *
     * @param orderCode 订单号
     * @param periods   排期
     * @return
     */
    @Override
    public EnterpriseScheduleDto getSchedule(Long orderCode, int periods) {
        return Convert.toEnterpriseScheduleDto(enterpriseScheduleMapper.getByOrderCodeAndPeriods(orderCode, periods));
    }

    /**
     * 获取企业订单排期信息
     *
     * @param orderCode 订单号
     * @return List
     */
    @Override
    public List<EnterpriseScheduleDto> getSchedule(Long orderCode) {
        return Convert.toEnterpriseScheduleDtoList(enterpriseScheduleMapper.getByOrderCode(orderCode, null));
    }

    /**
     * 获取企业订单排期信息
     *
     * @param orderCode 订单号
     * @param state     状态
     * @return List
     */
    @Override
    public List<EnterpriseScheduleDto> getSchedule(Long orderCode, EnterpriseScheduleStateEnum state) {
        return Convert.toEnterpriseScheduleDtoList(enterpriseScheduleMapper.getByOrderCode(orderCode, state.getValue()));
    }

    /**
     * 还款修改状态
     *
     * @param scheduleId    排期id
     * @param arrivalAmount 实付金额
     * @param payTime       支付时间
     * @return boolean
     */
    @Override
    public boolean modifyRepay(Integer scheduleId, BigDecimal arrivalAmount, LocalDateTime payTime) {
        return enterpriseScheduleMapper.modifyRepay(scheduleId, arrivalAmount, payTime,
                EnterpriseScheduleStateEnum.ALREADY.getValue(),
                EnterpriseScheduleStateEnum.NO.getValue()) > 0;
    }

    /**
     * 获取当前应还排期
     *
     * @param orderCode 订单号
     * @return EnterpriseScheduleDto
     */
    @Override
    public EnterpriseScheduleDto getCurrent(Long orderCode) {
        return Convert.toEnterpriseScheduleDto(enterpriseScheduleMapper
                .getCurrent(orderCode, EnterpriseScheduleStateEnum.NO.getValue()));
    }

    @Override
    public List<EnterpriseScheduleDto> getScheduleByOrderCodes(List<Long> orderCodes) {
        List<EnterpriseScheduleDto> res = new ArrayList<>();
        List<EnterpriseScheduleBean> list = enterpriseScheduleMapper.getByOrderCodes(orderCodes);
        if (list != null && list.size() > 0) {
            for (EnterpriseScheduleBean enterpriseScheduleBean : list) {
                if (enterpriseScheduleBean != null) {
                    EnterpriseScheduleDto dto = Convert.toEnterpriseScheduleDto(enterpriseScheduleBean);
                    res.add(dto);
                }
            }
        }
        return res;
    }


}
